const { Service } = require("egg");
const { Op } = require("sequelize");
class BaseService extends Service {
	table;
	Op = Op;
	userInfo = null;
	/**
	 * @var {logService}
	 */
	log = null;
	error = null;
	constructor(app) {
		super(app);
		this.log = this.ctx.service.logService
	}

	/**
	 * 优化PAGE SIZE
	 */
	getPageAndSize() {
		let { page = 1, size = 10 } = this.ctx.query;
		page = parseInt(page) || 1;
		size = parseInt(size) || 10;
		return { page, size };
	}
	// 事务
	async transaction(callback) {
		const transaction = await this.ctx.model.transaction();
		try {
			await callback(transaction);
		} catch (error) {
			await transaction.rollback();
			this.error = error;
			return false;
		}
		await transaction.commit();
		return true;
	}
	/**
	 * 保存数据
	 * @param {Object} data 
	 * @returns 
	 */
	async save(data, transaction = null) {
		return await this.table.create(data, { transaction });
	}
	/**
	 * 批量保存
	 */
	async saveAll(data, transaction = null) {
		return await this.table.bulkCreate(data, { transaction });
	}
	/**
	 * 
	 * @param {Object} query 
	 * @param {Array} order 
	 * @param {Array} attributes 
	 * @returns 
	 */
	async select(query, order, attributes) {
		return await this.table.findAll({
			where: query,
			order: order,
			attributes: attributes
		});
	}
	/**
	 * 
	 * @param {Object} query 
	 * @param {Number} page 
	 * @param {Number} pageSize 
	 * @param {Array} order 
	 * @param {Array} attributes 
	 * @param {Array} include 
	 * @returns 
	 */
	async page(query = {}, page = 1, pageSize = 10, order = [['id', "desc"]], attributes = ["*"], include = []) {
		return this.success(await this.table.findAndCountAll({
			distinct: true,
			where: query,
			offset: (page - 1) * pageSize,
			limit: pageSize,
			order: order,
			attributes: attributes,
			include: include
		}));
	}
	async show(id, attributes = [], include = []) {
		let where = {}
		if (typeof id === 'object') {
			where = id;
		}
		else {
			where.id = id;
		}
		return await this.table.findOne({
			distinct: true,
			where,
			attributes,
			include
		});
	}
	async queryUpdate(query, data, transaction = null) {
		return await this.table.update(data, {
			where: query,
			transaction
		});
	}
	async update(id, data, transaction = null) {
		let where = {}
		if (typeof id === 'object') {
			where = id;
		}
		else {
			where.id = id;
		}
		return await this.table.update(data, {
			where,
			transaction
		});
	}
	/**
	 * 逻辑删除
	 * @param {*} id 
	 * @param {*} transaction 
	 * @returns 
	 */
	async destroy(id, transaction = null) {
		let where = {}
		if (typeof id === 'object') {
			where = id;
		}
		else {
			where.id = id;
		}
		return await this.table.destroy({
			where,
			transaction
		});
	}
	/**
	 * @param {*} query 
	 * @returns 
	 */
	async count(query = {}) {
		return this.table.count({
			where: query
		});
	}
	/**
	 * 获取某个字段
	 * @param {*} query 
	 * @param {*} field 
	 * @returns 
	 */
	async value(query, field) {
		return this.table.findOne({
			where: query,
			attributes: [field]
		});
	}
	/**
	 * 获取某个字段数组
	 */
	async values(query, field) {
		let result = this.table.findAll({
			where: query,
			attributes: [field]
		});
		return result.map(item => item[field]);
	}

	/**
	 * token
	 */
	getToken(obj) {
		return this.app.jwt.sign(obj, this.app.config.jwt.secret, { expiresIn: this.app.config.jwt.expiresIn });
	}
	success(data) {
		return this.ctx.body = { code: 0, message: 'success', data: data ?? {} }
	}
	fail(message, code = -1, data = {}) {
		this.ctx.status = 400;
		return this.ctx.body = { code, message, data: data }
	}

}

module.exports = BaseService;